package com.yesep.learn.design.structural.facade;

import com.yesep.learn.design.common.pojo.*;
import com.yesep.learn.design.common.util.*;

/**
 * 外观模式（Facade Pattern），也被称为门面模式，是一种结构型设计模式。
 * 它的主要目的是简化复杂的子系统接口，为客户程序提供一个单一的、统一的访问接口，从而降低客户程序与子系统之间的耦合度，提高系统的灵活性和可维护性。
 * 以下是对外观模式的详细解析：
 * <p>
 * 一、定义与原理
 * 外观模式定义了一个高层接口，这个接口使得子系统更加容易使用。通过外观类，客户程序可以直接与外观类交互，而无需与子系统中的多个类进行复杂的交互。
 * 外观类将复杂的子系统封装在其内部，只暴露一个简单的接口给外部，从而隐藏了子系统的复杂性和实现细节。
 * <p>
 * 二、核心组件
 * 外观类（Facade）：这是外观模式的核心。外观类提供了一个统一的接口，客户程序通过这个接口与系统进行交互。
 * 外观类内部包含了与子系统的交互逻辑，客户程序无需直接与子系统交互。
 * 子系统（Subsystem）：子系统是系统中复杂功能或模块的集合。每个子系统都有自己的接口和实现，它们被外观类封装起来，对客户程序不可见。
 * 客户程序（Client）：客户程序是使用外观模式的对象。客户程序通过外观类提供的接口与系统交互，而无需关心子系统的具体实现。
 * 三、优点
 * 简化接口：外观类为复杂子系统提供了一个简单的接口，降低了客户程序与子系统之间的耦合度。
 * 易于维护：当子系统发生变化时，只需修改外观类，而无需修改客户程序，提高了系统的可维护性。
 * 灵活性：外观模式提供了良好的扩展性，可以很容易地添加新的子系统或移除现有的子系统，而不会对客户程序造成太大影响。
 * 提高安全性：由于客户程序通过外观类与子系统交互，可以在外观类中封装一些安全检查或限制条件，从而提高了系统的安全性。
 * 四、缺点
 * 不易限制客户对子系统的直接访问：外观模式并不能完全限制客户程序直接访问子系统，如果客户程序绕过外观类直接访问子系统，将会破坏系统的封装性和安全性。
 * 增加外观类的复杂性：随着子系统的增加和复杂性的提高，外观类可能会变得越来越复杂，从而增加了开发和维护的难度。
 * 五、应用场景
 * 当子系统非常复杂时：如果系统中有多个复杂的子系统，且这些子系统之间需要频繁交互，可以使用外观模式来简化接口，降低耦合度。
 * 当需要为复杂系统提供一个简单的接口时：在设计复杂的系统时，为了方便用户操作或提高系统的易用性，可以为系统提供一个简单的接口，通过外观模式来实现。
 * 当需要层次化设计系统时：在层次化设计系统中，可以使用外观模式来定义每一层的入口，降低层与层之间的耦合度。
 * 六、示例
 * 假设我们有一个家庭影院系统，它由DVD播放器、音响和投影仪等多个子系统组成。
 * 我们可以使用外观模式来设计一个家庭影院外观类（HomeTheaterFacade），该类封装了DVD播放器、音响和投影仪的复杂操作，并提供了一个简单的接口给客户程序使用。
 * 客户程序只需要与家庭影院外观类交互，就可以轻松控制整个家庭影院系统。
 */
public class Main {
    public static void main(String[] args) {
        CPUComponent cpu = DemoUtil.createCPUComponent();
        RAMComponent memory = DemoUtil.createRAMComponent();
        StorageComponent hard = DemoUtil.createStorageComponent();
        ComputerFacade computer = new ComputerFacade(cpu, memory, hard);
        computer.startComputer();
        computer.executeCommand("create file abc.txt");
        computer.shutdownComputer();
    }
}
